package d0903;

public class Demo1 {
    public static void main(String[] args) throws Exception {
        a();
        System.out.println("结束!");
    }

    static void a() throws Exception {
        try {
            // 测试执行的代码
            b();
            // Unreachable catch block for RuntimeException.
            // It is already handled by the catch block for Exception
            // 子类异常必须写在 父异常的下面
        } catch (RuntimeException e) {
            e.printStackTrace();  // 打印异常
            throw e;
        } catch (Exception e) {
            System.out.println(e.getMessage()); // 编译期异常!
            System.out.println(e.getCause());  // null
        } finally {
            // 不管try中是否出现异常, finally 中的代码都会被执行
            // 一般用作释放资源
            System.out.println("finally中的代码一定会被执行");
        }
        // 程序回归到正常

    }

    static void b() throws Exception {
        e();  // Exception
        //d();  // RuntimeException
        c();  // NumberFormatException
        // NumberFormatException a;
    }

    static void c() {
        String s = "100abc";
        // NumberFormatException 数字转换异常
        int i = Integer.valueOf(s); // 字符串转int
        System.out.println(i);
    }

    static void d() {
        // 自定义构建异常
        RuntimeException e = new RuntimeException("程序出错了!");
        RuntimeException e1 = new RuntimeException("上面的代码出错了!", e);
        // 手工抛出异常
        throw e1;
    }

    // 如果某个方法抛出编译期异常, 必须在方法上声明
    static void e() throws Exception {
        Exception e = new Exception("编译期异常!");
        // Unhandled exception type Exception
        // 编译期异常必须在编码时处理
        throw e;
    }
}
